/*
 * 易族智汇（北京）科技有限公司 版权所有。
 * 未经许可，您不得使用此文件。
 * 官方地址：www.javamall.com.cn
 */
package com.enation.app.javashop.framework.security.sign;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.exception.SystemErrorCodeV1;
import com.google.common.base.CaseFormat;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.enation.app.javashop.framework.security.sign.SignUtil.checkSign;

/**
 * 签名更新wrapper
 * 更新的字段如果需要参与签名，应该使用此wrappr
 * 而不应该用UpdateChainWrapper
 * @author kingapex
 * @version 1.0
 * @data 2021/11/21 10:28
 **/
public class SignUpdateChainWrapper<T> {

    private Map<String, Object> params;
    private Class<T> clz;
    private UpdateChainWrapper<T> updateChainWrapper;
    private QueryWrapper<T> queryWrapper;
    private BaseMapper<T> baseMapper;

    public SignUpdateChainWrapper(BaseMapper<T> baseMapper, Class<T> clz) {
        updateChainWrapper = new UpdateChainWrapper(baseMapper);
        queryWrapper = new QueryWrapper();
        this.baseMapper = baseMapper;
        params = new HashMap();
        this.clz = clz;
    }


    public SignUpdateChainWrapper set(String column, Object val) {
        params.put(column, val);
        updateChainWrapper.set(column, val);
        return this;
    }

    public SignUpdateChainWrapper<T> set(boolean condition, String column, Object val) {
        updateChainWrapper.set(condition, column, val);
        if (condition) {
            params.put(column, val);
        }
        return this;
    }

    public SignUpdateChainWrapper eq(String column, Object val) {
        queryWrapper.eq(column, val);
        updateChainWrapper.eq(column, val);
        return this;
    }



    public boolean update() {

        boolean needSign = needSign();
        if (needSign) {

            //更新结果：只要有一个更新失败，就是失败
            boolean result = true;
            //如果需要签名，使用updateById 会导致切面生效并更新sign字段
            List<T> list = baseMapper.selectList(queryWrapper);

            if (!list.isEmpty()) {
                for (T entity : list) {
                    fillModifyField(entity);
                    int count = baseMapper.updateById(entity);
                    if (count != 1) {
                        result = false;
                    }
                }
            }
            return result;
        } else {
            return updateChainWrapper.update();
        }

    }

    private void fillModifyField(T entity) {
        params.forEach((key, value) -> {
            String underscore = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, key);
            Field field = ReflectionUtils.findField(entity.getClass(), underscore);
            ReflectionUtils.makeAccessible(field);
            ReflectionUtils.setField(field, entity, value);
        });
    }


    /**
     * 判读是否需要签名
     *
     * @return
     */
    private boolean needSign() {
        T a = null;
        for (String key : params.keySet()) {
            String underscore = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, key);
            Field field = ReflectionUtils.findField(clz, underscore);
            if (field != null) {
                if (field.getAnnotation(SignField.class) != null) {
                    return true;
                }
            }
        }
        return false;
    }

}
